package view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import networkInterface.NetworkInterfaceBase;

import logging.Logger;

import object.Connection;
import object.Node;
import util.ConnectionUtil;
import util.NodeUtil;
import util.Settings;

public class Map extends JPanel{
	private static final long serialVersionUID = -4306558850797217068L;
	
	private ArrayList<Node> nodes;
	private ArrayList<NodeEllipse> nodeEll = new ArrayList<NodeEllipse>();
	private ArrayList<ConnectionLine> connLine = new ArrayList<ConnectionLine>();
	private boolean clickEvent = false;
	private Map thisMap = this;
	
	public Map(final ArrayList<Node> nodes){
		this.nodes = nodes;
		this.addMouseListener(new MouseListener() {
			@Override
			public void mouseClicked(MouseEvent event) {
				if(clickEvent == true)
					return;
				int x = event.getX();
				int y = event.getY();
				Logger.getInstance().log(Logger.TRACE, "Map.mouseClicked x:" + x + " y:" + y);
				boolean found = false;
				clickEvent = true;
				Node remThisNode = null;
				for(NodeEllipse n : nodeEll){
					if(n.ellipse.contains(x, y)){
						Color curColor = n.node.color;
						n.node.color = Settings.getInstance().getSelectedColor();
						thisMap.repaint();
						String message = "X: " + n.node.getX() + "   Y: " + n.node.getY() + 
								"\nCurrent Connections: "+ n.node.getConnections().size() + (n.node.getConnections().size()>0 ? "\n\nInterfaces:" : "");
						StringBuilder b = new StringBuilder();
						for(NetworkInterfaceBase netInt : n.node.getInterfaces()){
							b.append((netInt.getConnections().size() > 0 ? "\nUsed: " : "\nUnused: ") + netInt.getClass());
						}
						message += b.toString();
//						JOptionPane.showMessageDialog(null, message, "Node Information", JOptionPane.INFORMATION_MESSAGE);
						Object[] options = {"Ok", "Delete Node"};
						int selected = JOptionPane.showOptionDialog(null,
								message,
								"Node",
								JOptionPane.YES_NO_OPTION,
								JOptionPane.PLAIN_MESSAGE,
								null,
								options,
								options[0]);
						if(selected==1)
							remThisNode = n.node;
						//TODO: MAKE A PANEL FOR THIS AND RESET COLORS AT THE END
						found = true;
						n.node.color = curColor;
						break;
					}
				}
				if(!found){
					for(ConnectionLine c : connLine){
						if(c.line.ptLineDist(x, y) < 5){
							Color curColor = c.conn.color;
							c.conn.color = Settings.getInstance().getSelectedColor();
							thisMap.repaint();
							String message = ConnectionUtil.getBetterConnection(c.conn).getClass() + "\nNode 1: X: " + c.conn.getN1X() + "   Y: " + c.conn.getN1Y() + 
									"\nNode 2:  X: " + c.conn.getN2X() + "   Y: " + c.conn.getN2Y() + 
									"\nLength: " + c.conn.getLength();
							JOptionPane.showMessageDialog(null, message, "Connection Information", JOptionPane.INFORMATION_MESSAGE);
							//TODO: MAKE A PANEL FOR THIS AND RESET COLORS AT THE END
							found = true;
							c.conn.color = curColor;
							break;
						}
					}
				}
				javax.swing.SwingUtilities.invokeLater(new Runnable() {
					   public void run() { 
					       clickEvent = false;
					   }
					});
				if(remThisNode!=null)
					NodeUtil.removeNode(remThisNode, nodes);
				repaint();
			}
			@Override
			public void mouseEntered(MouseEvent e) {}
			@Override
			public void mouseExited(MouseEvent e) {}
			@Override
			public void mousePressed(MouseEvent e) {}
			@Override
			public void mouseReleased(MouseEvent e) {}
		});
	}
	public void paint(Graphics g2) {
		Logger.getInstance().log(Logger.TRACE, "Map.paint. Width: " + this.getWidth() + " Height:" + this.getHeight());
		
		Graphics2D g = (Graphics2D) g2;
		//background color
		g.setColor(Settings.getInstance().getBackColor());
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		nodeEll.clear();
		connLine.clear();
		for(Node n : nodes){
			g.setColor(n.color);
			
			Ellipse2D e = new Ellipse2D.Double(n.getX()-5, n.getY()-5, 10, 10);
			nodeEll.add(new NodeEllipse(n,e));
			g.fill(e);
			g.draw(e);
			
			ArrayList<Connection> thisConnections = n.getConnections();
			for(Connection c : thisConnections){
				g.setColor(c.color);
				Line2D l = new Line2D.Double(c.getN1X(), c.getN1Y(), c.getN2X(), c.getN2Y());
				g.draw(l);
				connLine.add(new ConnectionLine(c, l));
			}
			g.setColor(Settings.getInstance().getFrontColor());
		}
	}
	
	public class NodeEllipse{
		public NodeEllipse(Node n, Ellipse2D e) {
			node = n;
			ellipse = e;
		}
		public Node node;
		public Ellipse2D ellipse;
	}
	public class ConnectionLine{
		public ConnectionLine(Connection c, Line2D l) {
			conn = c;
			line = l;
		}
		public Connection conn;
		public Line2D line;
	}
}


